package geekTime.chapter24CompletableFuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * 烧水泡茶程序
 * 线程1：洗水壶->烧开水
 * 线程2：洗茶壶->洗茶杯->拿茶叶
 * 线程3：泡茶 需要等待线程1和线程2完成
 * Created by LinGer on 2019/7/2
 */
public class CompletableFutureTest {

    public static void main(String[] args) {
        //任务1
        CompletableFuture<Void> f1 = CompletableFuture.runAsync(() ->{
            System.out.println("T1:洗水壶...1min");
            sleep(1, TimeUnit.SECONDS);

            System.out.println("T1:烧开水...15min");
            sleep(15, TimeUnit.SECONDS);
        });

        //任务2
        CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() ->{
            System.out.println("T2:洗茶壶...1min");
            sleep(1, TimeUnit.SECONDS);

            System.out.println("T2:洗茶杯...2min");
            sleep(2, TimeUnit.SECONDS);

            System.out.println("T2:拿茶叶...1min");
            sleep(1, TimeUnit.SECONDS);

            return "龙井";
        });

        //任务3,等待任务1和任务2完成后执行：泡茶
        //lambda中的双下划线表示之后代码中用不到这个参数。java8会给出警告，java9会报错，java10支持
        CompletableFuture<String> f3 = f1.thenCombine(f2, (__, tf) ->{
            System.out.println("T1:拿到茶叶：" + tf);
            System.out.println("T1:泡茶...");

            return "T3:上茶：" + tf;
        });

        //等待任务3的执行结果
        System.out.println(f3.join());
    }

    public static void sleep(int t, TimeUnit u){
        try {
            u.sleep(t);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
